using System;
using System.Management.Automation;
using System.IO;
using System.Collections;

namespace PSSymbolStore
{
    public static class FileCopier
    {
        public static bool Copy(Cmdlet cmdlet, string source, string destination, bool compress)
        {
            if (!compress)
            {
                return Copy(cmdlet, source, destination);
            }
            return CopyCompressed(cmdlet, source, destination);
        }

        public static bool Copy(Cmdlet cmdlet, string source, string destination)
        {
            if (String.IsNullOrEmpty(source))
            {
                throw new ArgumentException("source");
            }

            if (String.IsNullOrEmpty(destination))
            {
                throw new ArgumentException("destination");
            }

            if (!File.Exists(source))
            {
                throw new FileNotFoundException("The source file was not found", source);
            }

            if (!File.Exists(destination))
            {
                if ((cmdlet == null) || cmdlet.ShouldProcess(destination, "Copy " + source + " to"))
                {
                    if (cmdlet != null) { cmdlet.WriteDebug("Copying " + source + " to " + destination); }

                    File.Copy(source, destination);
                    return true;
                }
                return false;
            }
            
            if (cmdlet != null) { cmdlet.WriteDebug("A file exists at \"" + destination + "\", symbol file not copied"); }
            return true;
        }

        public static bool CopyCompressed(Cmdlet cmdlet, string source, string destination)
        {
            if (String.IsNullOrEmpty(source))
            {
                throw new ArgumentException("source");
            }

            if (String.IsNullOrEmpty(destination))
            {
                throw new ArgumentException("destination");
            }

            if (!File.Exists(source))
            {
                throw new FileNotFoundException("The source file was not found", source);
            }

            if (!destination.EndsWith("_", StringComparison.InvariantCultureIgnoreCase))
            {
                string newDestination = Helpers.GetCompressedFilePath(destination);
                if (cmdlet != null) { cmdlet.WriteDebug("Compressing the file and changing destination from " + destination + " to " + newDestination); }
                destination = newDestination;
            }

            if (!File.Exists(destination))
            {
                if ((cmdlet == null) || (cmdlet.ShouldProcess(destination, "Copy " + source + " to")))
                {
                    // Compress the source file into a temporary file and move the temporary file to the destination
                    string tempFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

                    if (cmdlet != null)
                    {
                        cmdlet.WriteDebug("Compressing " + source + " to " + tempFile);
                    }

                    var compress = new CabLib.Compress();
                    compress.SetEncryptionKey("");
                    var list = new ArrayList {new[] {source, Path.GetFileName(source)}};
                    // Add the source file, referencing it by filename only in the zip
                    compress.CompressFileList(list, tempFile, 0x7FFFFFFF);
                    if (cmdlet != null) { cmdlet.WriteDebug("Successfully compressed " + source); }

                    // Move the temp file to the destination
                    if (cmdlet != null) { cmdlet.WriteDebug("Moving " + tempFile + " to " + destination); }
                    File.Move(tempFile, destination);

                    return true;
                }
                
                return false;
            }
            
            if (cmdlet != null) { cmdlet.WriteDebug("A file exists at \"" + destination + "\", symbol file not copied"); }
            return true;
        }
    }
}
